// IArchive.h

#ifndef __IARCHIVE_H
#define __IARCHIVE_H

#include "Common/Stream/IProgress.h"
#include "Common/Stream/IStream.h"
#include "Common/7Zip/PropID.h"


namespace Common
{
namespace Archive
{
	enum class FileTimeType
	{
		kWindows,
		kUnix,
		kDOS
	};
	
  enum class Property
  {
    kName = 0,
    kClassID,
    kExtension,
    kAddExtension,
    kUpdate,
    kKeepName,
    kStartSignature,
    kFinishSignature,
    kAssociate
  };

  namespace Extract
  {
      enum class AskMode
      {
        kExtract = 0,
        kTest,
        kSkip
      };
      enum class OperationResult
      {
        kOK = 0,
        kUnSupportedMethod,
        kDataError,
        kCRCError
      };
  }
  namespace Update
  {
      enum class OperationResult
      {
        kOK = 0,
        kError
      };
  }
}

}
  

MIDL_INTERFACE("23170F69-40C1-278A-0000-000600100000")
IArchiveOpenCallback: public IUnknown
{
  STDMETHOD(SetTotal)(const UINT64 *files, const UINT64 *bytes) PURE; 
  STDMETHOD(SetCompleted)(const UINT64 *files, const UINT64 *bytes) PURE; 
};



MIDL_INTERFACE("23170F69-40C1-278A-0000-000600200000")
IArchiveExtractCallback: public IProgress
{
  /* INTERFACE IProgress */ 
  STDMETHOD(SetTotal)(UINT64 total) PURE; 
  STDMETHOD(SetCompleted)(const UINT64 *completeValue) PURE; 
  
  STDMETHOD(GetStream)(UINT32 index, ISequentialOutStream **outStream,  INT32 askExtractMode) PURE; 
  STDMETHOD(PrepareOperation)(INT32 askExtractMode) PURE; 
  STDMETHOD(SetOperationResult)(INT32 resultEOperationResult) PURE; 
};

MIDL_INTERFACE("23170F69-40C1-278A-0000-000600300000")
IArchiveOpenVolumeCallback: public IUnknown
{
  STDMETHOD(GetProperty)(PROPID propID, PROPVARIANT *value) PURE; 
  STDMETHOD(GetStream)(const wchar_t *name, IInStream **inStream) PURE;
};

MIDL_INTERFACE("23170F69-40C1-278A-0000-000600400000")
IInArchiveGetStream: public IUnknown
{
  STDMETHOD(GetStream)(UINT32 index, ISequentialInStream **stream) PURE;
};

MIDL_INTERFACE("23170F69-40C1-278A-0000-000600500000")
IArchiveOpenSetSubArchiveName: public IUnknown
{
  STDMETHOD(SetSubArchiveName)(const wchar_t *name) PURE;
};


/*
IInArchive::Extract:
  indices must be sorted
  numItems = 0xFFFFFFFF means "all files"
  testMode != 0 means "test files without writing to outStream"
*/

//This interface is exported from 7z dll
MIDL_INTERFACE("23170F69-40C1-278A-0000-000600600000")
IInArchive: public IUnknown
{
  STDMETHOD(Open)(IInStream *stream, const UINT64 *maxCheckStartPosition, IArchiveOpenCallback *openArchiveCallback) PURE; 
  STDMETHOD(Close)() PURE; 
  STDMETHOD(GetNumberOfItems)(UINT32 *numItems) PURE; 
  STDMETHOD(GetProperty)(UINT32 index, PROPID propID, PROPVARIANT *value) PURE; 
  STDMETHOD(Extract)(const UINT32* indices, UINT32 numItems, INT32 testMode, IArchiveExtractCallback *extractCallback) PURE; 
  STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value) PURE; 
  STDMETHOD(GetNumberOfProperties)(UINT32 *numProperties) PURE; 
  STDMETHOD(GetPropertyInfo)(UINT32 index, BSTR *name, PROPID *propID, VARTYPE *varType) PURE; 
  STDMETHOD(GetNumberOfArchiveProperties)(UINT32 *numProperties) PURE; 
  STDMETHOD(GetArchivePropertyInfo)(UINT32 index, BSTR *name, PROPID *propID, VARTYPE *varType) PURE;
};

MIDL_INTERFACE("23170F69-40C1-278A-0000-000600610000")
IArchiveOpenSeq: public IUnknown
{
  STDMETHOD(OpenSeq)(ISequentialInStream *stream) PURE;
};

MIDL_INTERFACE("23170F69-40C1-278A-0000-000600800000")
IArchiveUpdateCallback: public IProgress
{
  /* INTERFACE_IProgress(x) */ 
  STDMETHOD(SetTotal)(UINT64 total) PURE;
  STDMETHOD(SetCompleted)(const UINT64 *completeValue) PURE;
  
  STDMETHOD(GetUpdateItemInfo)(UINT32 index,  
      INT32 *newData, /*1 - new data, 0 - old data */ 
      INT32 *newProperties, /* 1 - new properties, 0 - old properties */ 
      UINT32 *indexInArchive /* -1 if there is no in archive, or if doesn't matter */ 
      )  PURE;
  STDMETHOD(GetProperty)(UINT32 index, PROPID propID, PROPVARIANT *value) PURE;
  STDMETHOD(GetStream)(UINT32 index, ISequentialInStream **inStream) PURE;
  STDMETHOD(SetOperationResult)(INT32 operationResult) PURE;
};

MIDL_INTERFACE("23170F69-40C1-278A-0000-000600820000")
IArchiveUpdateCallback2: public IArchiveUpdateCallback
{
  /* INTERFACE IProgress */ 
  STDMETHOD(SetTotal)(UINT64 total) PURE;
  STDMETHOD(SetCompleted)(const UINT64 *completeValue) PURE;
  
  /* INTERFACE IArchiveUpdateCallback */
  STDMETHOD(GetUpdateItemInfo)(UINT32 index,  
      INT32 *newData, /*1 - new data, 0 - old data */ 
      INT32 *newProperties, /* 1 - new properties, 0 - old properties */ 
      UINT32 *indexInArchive /* -1 if there is no in archive, or if doesn't matter */ 
      )  PURE;
  STDMETHOD(GetProperty)(UINT32 index, PROPID propID, PROPVARIANT *value) PURE;
  STDMETHOD(GetStream)(UINT32 index, ISequentialInStream **inStream) PURE;
  STDMETHOD(SetOperationResult)(INT32 operationResult) PURE;
  
  // Interface IArchiveUpdateCallback2
  STDMETHOD(GetVolumeSize)(UINT32 index, UINT64 *size) PURE; 
  STDMETHOD(GetVolumeStream)(UINT32 index, ISequentialOutStream **volumeStream) PURE;
};

 
//This interface is exported from 7z dll
MIDL_INTERFACE("23170F69-40C1-278A-0000-000600A00000")
IOutArchive: public IUnknown
{
	STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UINT32 numItems, IArchiveUpdateCallback *updateCallback) PURE; 
	STDMETHOD(GetFileTimeType)(UINT32 *type) PURE;
};


MIDL_INTERFACE("23170F69-40C1-278A-0000-000600030000")
ISetProperties: public IUnknown
{
  STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, INT32 numProperties) PURE;
};

#endif
